package com.example.server.service.admin.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.server.common.constant.EnableConstants;
import com.example.server.common.constant.Result;
import com.example.server.common.utils.redis.RedisUtil;
import com.example.server.entity.Button;
import com.example.server.entity.Menu;
import com.example.server.entity.MenuButton;
import com.example.server.mapper.ButtonMapper;
import com.example.server.mapper.MenuButtonMapper;
import com.example.server.mapper.MenuMapper;
import com.example.server.service.admin.ButtonService;
import com.example.server.service.admin.MenuButtonService;
import com.example.server.service.admin.MenuService;
import com.example.server.vo.ButtonVO;
import com.example.server.vo.MenuVO;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

/**
 * @author china.fuyao@outlook.com
 * @date 2020-04-19 15:21
 */
@Service("menuService")
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements MenuService {
    private static final String MENU_CATCH = "sys:menu:list";
    private static final String MY_MENU_CATCH = "sys:menu:my:";

    @Resource
    RedisUtil redisUtil;
    @Resource
    ButtonService buttonService;
    @Resource
    MenuButtonService menuButtonService;

    /**
     * 初始化数据
     */
    private List<Menu> Init(int force) {
        Object obj = redisUtil.get(MENU_CATCH);
        List<Menu> r;
        if (1 == force || obj == null) {
            r = list(new QueryWrapper<Menu>().eq("status", EnableConstants.ENABLE).orderByAsc("sort"));
            if (r == null) {
                r = new ArrayList<>();
            }
            redisUtil.set(MENU_CATCH, r);
        } else {
            r = (ArrayList<Menu>) obj;
        }
        return r;
    }

    /**
     * 菜单列表
     *
     * @param force
     * @return
     */
    @Override
    public Result menuList(Integer force) {
        return new Result(Init(force));
    }

    /**
     * 菜单按钮列表
     *
     * @return
     */
    @Override
    public Result buttonList() {
        List<Button> list = buttonService.list(new QueryWrapper<Button>().eq("status", EnableConstants.ENABLE).orderByAsc("sort"));
        return new Result(list);
    }

    /**
     * 指定角色菜单列表
     *
     * @param roleId
     * @param force
     * @return
     */
    @Override
    public Result menuListByRoleId(Integer roleId, Integer force) {
        Object cacheList = redisUtil.get(MY_MENU_CATCH + roleId);
        if (1 == force || null == cacheList) {
            List<Map> list = baseMapper.menuListByRoleId(roleId);
            redisUtil.set(MY_MENU_CATCH + roleId, list);
            return new Result(list);
        }
        return new Result(cacheList);
    }

    /**
     * 全部按钮列表
     *
     * @return
     */
    @Override
    public Result buttonAllList() {
        return new Result(buttonService.list());
    }

    /**
     * 新增菜单
     *
     * @param menuVO
     * @param customerId
     * @return
     */
    @Override
    public Result addMenu(MenuVO menuVO, Integer customerId) {
        Menu menu = new Menu();
        menu.setPid(menuVO.getPid());
        menu.setMenuName(menuVO.getMenuName());
        menu.setUrl(menuVO.getUrl());
        menu.setSort(menuVO.getSort());
        menu.setIcon(menuVO.getIcon());
        menu.setBtnIds(menuVO.getBtnId());
        menu.setStatus(menuVO.getStatus());
        menu.setAddUid(customerId);
        boolean save = save(menu);
        if (save) {
            Init(1);
            return Result.OK();
        }
        return Result.Error();
    }

    /**
     * 修改菜单
     *
     * @param menuVO
     * @param customerId
     * @return
     */
    @Override
    @Transactional
    public Result updateMenu(MenuVO menuVO, Integer customerId) {
        if (null == menuVO || null == menuVO.getMenuId()) {
            return Result.Error("请求参数异常");
        }
        Menu menu = getById(menuVO.getMenuId());
        menu.setPid(menuVO.getPid());
        menu.setMenuName(menuVO.getMenuName());
        menu.setUrl(menuVO.getUrl());
        menu.setSort(menuVO.getSort());
        menu.setIcon(menuVO.getIcon());
        menu.setBtnIds(menuVO.getBtnId());
        menu.setStatus(menuVO.getStatus());
        menu.setAddUid(customerId);
        boolean update = updateById(menu);
        if (update) {
            menuButtonService.update(new UpdateWrapper<MenuButton>()
                    .eq("menu_id", menu.getMenuId()).set("btn_ids", menu.getBtnIds()));
            Init(1);
            return Result.OK();
        }
        return Result.Error();
    }

    /**
     * 删除菜单
     *
     * @param menuId
     * @param customerId
     * @return
     */
    @Override
    public Result delMenu(Integer menuId, Integer customerId) {
        List<Menu> pid = list(new QueryWrapper<Menu>().eq("pid", menuId));
        if (null != pid && pid.size() > 0) {
            Set<Integer> set = new HashSet<>(pid.size());
            pid.forEach(menu -> set.add(menu.getMenuId()));
            set.add(menuId);
            boolean remove = removeByIds(set);
            if (remove) {
                Init(1);
                return Result.OK();
            }
        } else {
            boolean remove = removeById(menuId);
            if (remove) {
                Init(1);
                return Result.OK();
            }
        }
        return Result.Error();
    }

    /**
     * 新增按钮
     *
     * @param buttonVO
     * @param customerId
     * @return
     */
    @Override
    public Result addButton(ButtonVO buttonVO, Integer customerId) {
        return buttonService.addButton(buttonVO, customerId);
    }

    /**
     * 修改按钮
     *
     * @param buttonVO
     * @param customerId
     * @return
     */
    @Override
    public Result updateButton(ButtonVO buttonVO, Integer customerId) {
        return buttonService.updateButton(buttonVO, customerId);
    }

    /**
     * 删除按钮
     *
     * @param buttonId
     * @param customerId
     * @return
     */
    @Override
    public Result delButton(Integer buttonId, Integer customerId) {
        return buttonService.delButton(buttonId, customerId);
    }
}
